package com.glacier.cloud.order.service.impl;

import com.glacier.cloud.order.consts.Constant;
import com.glacier.cloud.order.dao.OrderItemMapper;
import com.glacier.cloud.order.dao.OrderMapper;
import com.glacier.cloud.order.entity.dataobject.OrderDo;
import com.glacier.cloud.order.entity.dataobject.OrderItemDo;
import com.glacier.cloud.order.entity.dto.cmd.OrderCreatCmd;
import com.glacier.cloud.order.entity.dto.cmd.ProductCmd;
import com.glacier.cloud.order.entity.event.OrderCreateEvent;
import com.glacier.cloud.order.entity.event.ProductEvent;
import com.glacier.cloud.order.service.CartService;
import com.glacier.cloud.order.service.OrderService;
import com.glacier.cloud.order.service.ProductService;
import io.seata.spring.annotation.GlobalTransactional;
import jakarta.annotation.Resource;
import org.springframework.cloud.stream.function.StreamBridge;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * date 2024-01-04 13:40
 *
 * @author glacier
 * @version 1.0
 */
@Transactional(readOnly = true)
@Service
public class OrderServiceImpl implements OrderService {
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private OrderItemMapper orderItemMapper;
    @Resource
    private ProductService productService;
    @Resource
    private CartService cartService;
    @Resource
    private StreamBridge streamBridge;


    /**
     * 创建订单
     * 主服务添加@GlobalTransactional，子服务不必添加
     * 配置了全部异常处理后，子服务抛出异常后，主服务不会回滚，可手动回滚
     *
     * @param command
     * @return
     */
    @GlobalTransactional(rollbackFor = {Exception.class})
    @Transactional(rollbackFor = {Exception.class})
    @Override
    public int createOrder(OrderCreatCmd command) {
        // 创建订单
        OrderDo orderDo = new OrderDo();
        orderDo.setCustomerUserId(command.getCustomerUserId());
        orderDo.setOrderSn(UUID.randomUUID().toString().replace("-", ""));
        orderDo.setCreateTime(LocalDateTime.now());
        int update = orderMapper.insert(orderDo);

        createOrderDetail(command, orderDo);
        // 锁定库存
        productService.lockProductStock(command, orderDo.getId());
        // 从购物车移除
        cartService.removeProduct(command);
//        int i = 1 / 0;
        // 发送消息
        sendMessage(command, orderDo.getId());
        return update;
    }

    /**
     * 发送消息
     *
     * @param command
     * @param orderId
     * @return
     */
    private void sendMessage(OrderCreatCmd command, Long orderId) {
        List<ProductEvent> productEvents = command.getProducts()
                .stream()
                .map(e -> new ProductEvent(e.getProductSkuId(), e.getQuantity()))
                .collect(Collectors.toList());
        streamBridge.send(Constant.ORDER_OUT, new OrderCreateEvent(orderId, command.getCustomerUserId(), productEvents));
    }

    /**
     * 创建订单详情
     *
     * @param command
     * @param orderDo
     */
    private void createOrderDetail(OrderCreatCmd command, OrderDo orderDo) {
        for (ProductCmd product : command.getProducts()) {
            // 创建订单项
            OrderItemDo orderItemDo = new OrderItemDo();
            orderItemDo.setOrderId(orderDo.getId());
            orderItemDo.setOrderSn(orderDo.getOrderSn());
            orderItemDo.setCustomerUserId(command.getCustomerUserId());
            orderItemDo.setProductSkuId(product.getProductSkuId());
            orderItemDo.setProductQuantity(product.getQuantity());
            orderItemDo.setCreateTime(LocalDateTime.now());
            orderItemMapper.insert(orderItemDo);
        }
    }
}
